class RandomWeight:
    def __init__(self, list_weight, point_repeat=0, point=100):
        self.point_repeat = point_repeat
        self.weight_list = list_weight
        self.point = point
        self.rand_max = 0.00
        for weight in self.weight_list:
            self.rand_max += weight['point']
        self.complete = []
        self.max_loop = 100

    def PseudoRandom(self, point, is_bool=True):
        _min = 1
        i = _min
        from random import randint
        while True:
            if self.max_loop <= _min:
                self.max_loop = 100
                i = _min
                yield False if is_bool else self.max_loop
            rand = int(randint(_min, self.max_loop))
            if rand <= 0: rand = _min
            if _min < rand < point:
                self.max_loop = 100
                i = _min
                yield True if is_bool else rand
            else:
                import math
                offset = (math.pow(int(point / 10), int(point / 10)))
                if offset <= 1: offset = 5
                self.max_loop -= int(point / offset)
                i += _min
                yield False if is_bool else rand

    def RandomWeight(self):
        from random import randint
        _min = 1
        rand = _min + round(randint(_min, self.rand_max * self.point) / self.point, 2)
        for _list in self.weight_list:
            _max = round(_min + float(_list['point']), 2)
            if _min <= rand < _max:
                return _list['list']
            else:
                _min = _max

    def Random(self, num=1, must_number=0, must_list=None):
        assert num >= 0, AttributeError("num >= 1")
        i = 0
        while i < num:
            i += 1
            if self.point_repeat > 0:
                from random import randint
                rand = randint(0, 99)
                if 0 <= rand < self.point_repeat:
                    self.complete.append(self.RandomList(self.RandomWeight()))
                else:
                    i -= 1
            else:
                self.complete.append(self.RandomList(self.RandomWeight()))
        if must_list:
            from random import sample
            _i = 0
            while _i < must_number:
                self.complete.remove(sample(self.complete, 1)[0])
                _i += 1
            _i = 0
            while _i < must_number:
                self.complete.append(sample(must_list, 1)[0])
                _i += 1
        return self.complete

    def RandomAttr(self, distribution_number, distribution_count, minimum):
        _list = []
        from random import randint
        _max = int(distribution_number / distribution_count)
        _distribution_number = distribution_number
        i = 0
        while i < distribution_count:
            rand = randint(minimum, _max)
            _list.append(rand)
            _distribution_number -= rand
            i += 1
        i = 0
        __list = []
        from random import sample
        while i < distribution_count:
            i += 1
            item = sample(_list, 1)[0]
            _list.remove(item)
            if i != distribution_count:
                rand = randint(0, _distribution_number)
                _distribution_number -= rand
            else:
                rand = _distribution_number
            __list.append(item + rand)

        from random import shuffle
        shuffle(__list)
        return __list

    def RandomList(self, _list):
        from random import sample
        return sample(list(_list), 1)[0]


if __name__ == "__main__":
    weight_list = [{"point": 0.22, "list": [1, 2, 3, 4, 5, 6]}, {"point": 20, "list": [7, 8, 9, 10]},
                   {"point": 30, "list": [11, 12, 13, 14, 15, 16]},
                   {"point": 49, "list": [99, 98, 97, 96, 95, 94, 93, 92, 91, 90]}]
    rw = RandomWeight(weight_list)
    a = rw.Random(10)
    b = rw.RandomAttr(600, 3, 100)
    c = rw.PseudoRandom(37)
    print(a)
    print(b)
    s = 0
    for x in range(100):
        d = c.__next__()
        if d:
            s += 1
    print(s)
